package com.sec.android.app.myfiles.facade.cmd;

import android.app.Activity;
import android.os.Environment;
import android.widget.Toast;

import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.facade.MyFilesFacade;
import com.sec.android.app.myfiles.fragment.AbsMyFilesFragment;
import com.sec.android.app.myfiles.fragment.filelist.FileListFragment;
import com.sec.android.app.myfiles.info.FileType;
import com.sec.android.app.myfiles.log.SamsungAnalyticsLog;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.cloud.CloudFileRecord;
import com.sec.android.app.myfiles.module.download.DownloadFileRecord;
import com.sec.android.app.myfiles.module.local.file.LocalFileRecord;
import com.sec.android.app.myfiles.module.preview.CompressFileRecord;
import com.sec.android.app.myfiles.navigation.NavigationInfo;
import com.sec.android.app.myfiles.navigation.NavigationInfo.NavigationMode;
import com.sec.android.app.myfiles.navigation.NavigationManager;
import com.sec.android.app.myfiles.operation.FileOperator;
import com.sec.android.app.myfiles.util.FileExecute;
import com.sec.android.app.myfiles.util.FileUtils;
import com.sec.android.app.myfiles.util.Gear360ContentsExecutor;
import com.sec.android.app.myfiles.util.SemFwWrapper;
import com.sec.android.app.myfiles.util.UiUtils;

import org.puremvc.java.multicore.interfaces.INotification;
import org.puremvc.java.multicore.patterns.command.SimpleCommand;

import java.io.File;
import java.util.ArrayList;

public class ExecuteRecordCmd extends SimpleCommand {
    public static final String INTERNAL_DOWNLOAD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()
            + "/Android/data/com.sec.android.app.myfiles/files/";

    private NavigationInfo mCurInfo;

    @Override
    public void execute(INotification notification) {
        Object[] params = (Object[]) notification.getBody();

        int processId = (Integer) params[0];
        Activity activity = (Activity) params[1];
        FileRecord record = (FileRecord) params[2];

        NavigationManager naviMgr = NavigationManager.getInstance(processId);
        mCurInfo = naviMgr.getCurInfo();
        AbsMyFilesFragment fragment = null;

        if (mCurInfo != null) {
            fragment = mCurInfo.getCurFragment();
        }

        if (record.isDirectory()) {
            enterFolder(record, naviMgr, mCurInfo, fragment);
        } else {
            switch (record.getStorageType()) {
                case Cloud:
                    executeCloudFile(processId, record, activity, fragment);
                    break;
                case Downloads:
                    executeDownloadFile((DownloadFileRecord) record, activity, fragment);
                    break;
                default:
                    executeFile(processId, record, activity, fragment);
                    break;
            }
        }
    }

    private void executeDownloadFile(DownloadFileRecord record, Activity activity, AbsMyFilesFragment fragment) {
        if (fragment != null) {
            if (FileUtils.isSameAsRealFile(record)) {
                executeFile(fragment.getProcessId(), record, activity, fragment);
            } else {
                MyFilesFacade.downloadConfirm(fragment.getProcessId(), fragment.context(), fragment, record);
            }
        }
    }

    private void executeFile(int processId, FileRecord record, Activity activity, AbsMyFilesFragment fragment) {
        if (FileType.isArchiveFileType(record.getFileType())) {
            if (NavigationManager.isPossibleToActionMode(processId)) {
                saveListPosition(fragment, mCurInfo);
                FileRecord.StorageType storageType = record.getStorageType();
                if (storageType == FileRecord.StorageType.Recent ||
                        storageType == FileRecord.StorageType.Downloads
                        || storageType == FileRecord.StorageType.Shortcut) {
                    record = FileRecord.createFileRecord(FileRecord.StorageType.Local, record.getFullPath());
                }
                FileRecord compressRecord = new CompressFileRecord(record);
                NavigationInfo info = NavigationInfo.getInstance(NavigationInfo.NavigationMode.Preview_compress_item, compressRecord);
                info.setScreenPath(SamsungAnalyticsLog.ScreenPath.UNZIP_POPUP);
                NavigationManager.getInstance(processId).enter(info);
                FileUtils.updateRecentFile(activity, record);
            } else {
                if (record.isEncryptionFileType())
                    Toast.makeText(activity, R.string.file_lock, Toast.LENGTH_SHORT).show();
                else
                    Toast.makeText(activity, R.string.unable_to_open_file, Toast.LENGTH_SHORT).show();
            }
        } else if (record.isGear360Contents()) {
            new Gear360ContentsExecutor().executeGear360Contents(processId, activity, record);
        } else {
            if (fragment != null) {
                FileExecute.openFile(processId, record, activity);
            } else {
                Toast.makeText(activity, R.string.invalid_resource_path_specified, Toast.LENGTH_SHORT).show();
                MyFilesFacade.goHome(processId, null, activity);
            }
        }
    }

    private void executeCloudFile(int processId, FileRecord record, Activity activity, AbsMyFilesFragment fragment) {
        if (fragment != null && fragment.getFragmentManager() != null) {
            String googleDocsLink = ((CloudFileRecord) record).getGoogleDocsLink();

            if (googleDocsLink != null) {
                if (UiUtils.canExecuteCloud(activity, fragment.getFragmentManager())) {
                    FileUtils.openGoogleDocsFile(googleDocsLink, activity);
                }
            } else if (FileType.isArchiveFileType(record.getFileType())) {
                Toast.makeText(activity, R.string.unable_to_extract_cloud_zip_file, Toast.LENGTH_LONG).show();
            } else {
                File file = SemFwWrapper.file(INTERNAL_DOWNLOAD_PATH + ((CloudFileRecord) record).getFileId() + "/" + record.getName());

                if (file.exists()) {
                    executeFile(processId, new LocalFileRecord(file.getPath()), activity, fragment);
                } else if (UiUtils.canExecuteCloud(activity, fragment.getFragmentManager())) {
                    ArrayList<FileRecord> srcRecordList = new ArrayList<>();
                    srcRecordList.add(record);

                    if (mCurInfo.isNormalMode() || NavigationMode.Optimize_storage_files.equals(mCurInfo.getNavigationMode())) {// copy is not progressing
                        if (!FileOperator.isWorking()) {
                            CopyMoveCmd.clearSelectedList();
                            MyFilesFacade.copymoveRecord(fragment.getProcessId(), activity.getApplicationContext(), FileOperator.Operation.COPY,
                                    CopyMoveCmd.OperationProgress.DOWNLOAD_OPEN, fragment, srcRecordList, new LocalFileRecord(file.getParent()));
                        } else {
                            Toast.makeText(activity, R.string.unable_to_download_file, Toast.LENGTH_LONG).show();
                        }
                    }
                }
            }
        }
    }

    private void enterFolder(FileRecord record, NavigationManager naviMgr, NavigationInfo curInfo, AbsMyFilesFragment fragment) {
        NavigationInfo info;

        if (curInfo != null) {
            saveListPosition(fragment, curInfo);
            if (curInfo.getNavigationMode() == NavigationInfo.NavigationMode.Preview_compress_item) {
                info = NavigationInfo.getInstance(NavigationInfo.NavigationMode.Normal, record);
            } else {
                info = NavigationInfo.getInstance(curInfo, record);
            }
        } else {
            info = NavigationInfo.getInstance(NavigationInfo.NavigationMode.Normal, record);
        }
        naviMgr.enter(info);
    }

    private void saveListPosition(AbsMyFilesFragment fragment, NavigationInfo curInfo) {
        if (fragment instanceof FileListFragment && curInfo != null) {
            int listPosition = ((FileListFragment) fragment).getCurListPosition();
            curInfo.setCurListPosition(listPosition);
        }
    }
}
